package com.io.example.demoparent.ES.es;


import com.io.example.demoparent.ES.util.ESUtil;
import jakarta.validation.constraints.NotNull;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;


/*
    查询文档
 */
public class ES_Doc_Query {

    public static void main(String[] args) throws IOException {
        RestHighLevelClient restHighLevelClient = ESUtil.esRestClient( );
        SearchAggregationQuery(restHighLevelClient);
        restHighLevelClient.close( );
    }


    /**
     * 查询全部
     *
     * @param client
     * @throws IOException
     */
    public static void SearchAllQuery(RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        searchSourceBuilder.query(QueryBuilders.matchAllQuery( ));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }

    /**
     * 条件查询
     *
     * @param client
     * @throws IOException
     */
    public static void SearchQuery(RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        // QueryBuilders.termQuery() 指定条件er查询
        SearchSourceBuilder query = searchSourceBuilder.query(QueryBuilders.termQuery("age", 80));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }


    /**
     * 分页查询
     *
     * @param client
     * @throws IOException
     */
    public static void SearchPageQuery(RestHighLevelClient client, Integer from, Integer size) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        // QueryBuilders.termQuery() 指定条件er查询
        SearchSourceBuilder query = searchSourceBuilder.query(QueryBuilders.matchAllQuery( ));
        //排除字段
        String[] includes = {"userName", "age"};
        String[] excludes = {"gender"};
        query.fetchSource(includes, excludes);
        //当前页   （单当前页面码-1）*每页显示条数
        query.from((from - 1) * size);
        //一页有多少条数
        query.size(size);
        //按年龄排序
        query.sort("age", SortOrder.DESC);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }

    /**
     * 组合查询
     *
     * @param client
     * @throws IOException
     */
    public static void SearchGroupQuery(RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        // 组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery( );

     /*
   and 查询
        boolQueryBuilder.must(QueryBuilders.matchQuery("age",100));
        boolQueryBuilder.must(QueryBuilders.matchQuery("gender","女"));
        boolQueryBuilder.mustNot(QueryBuilders.matchQuery("gender","男"));*/
        //or 查询
        boolQueryBuilder.should(QueryBuilders.matchQuery("age", 100));
        boolQueryBuilder.should(QueryBuilders.matchQuery("age", 80));


        SearchSourceBuilder sourceBuilder = searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }


    /**
     * 范围查询
     *
     * @param client
     * @throws IOException
     */
    public static void SearchRangeQuery(RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        // 范围查询
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
        rangeQuery.gte(85);
        rangeQuery.lt(100);

        SearchSourceBuilder sourceBuilder = searchSourceBuilder.query(rangeQuery);
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }


    /**
     * 模糊查询
     *
     * @param client
     * @throws IOException
     */
    public static void SearchFuzzyQuery(RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        // 模糊查询
        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("userName", "王");
        // 偏差距离
//                .fuzziness( Fuzziness.ONE );

        SearchSourceBuilder sourceBuilder = searchSourceBuilder.query(fuzzyQueryBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }


    /**
     * 模糊查询
     *
     * @param client
     * @throws IOException
     */
    public static void SearchHighlighterQuery(RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        // 高亮查询
        TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("age", "100");
        SearchSourceBuilder sourceBuilder = searchSourceBuilder.query(termsQueryBuilder);


        HighlightBuilder highlightBuilder = new HighlightBuilder( );
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.field("userName");

        sourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(sourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        TimeValue took = response.getTook( );
        SearchHits hits = response.getHits( );
        hits.forEach(documentFields -> {
            String sourceAsString = documentFields.getSourceAsString( );
            System.out.println("sourceAsString = " + sourceAsString);
        });

        System.out.println("took = " + took);

    }


    /**
     * 聚合查询-平均值-最大\小值-分组
     *
     * @param client
     * @throws IOException
     */
    public static void SearchAggregationQuery(RestHighLevelClient client) throws IOException {
        //1. 创建请求对象
        SearchRequest request = new SearchRequest("user");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );
        //2. 设置条件
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("genderGroup").field("age").order(BucketOrder.count(true));

        searchSourceBuilder.aggregation(aggregationBuilder);

        request.source(searchSourceBuilder);
        //3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);


        Terms brandTerm = response.getAggregations( ).get("genderGroup");
        for (Terms.Bucket bucket : brandTerm.getBuckets( )) {
            System.out.println(bucket.getKey( ) + ":" + bucket.getDocCount( ));

            System.out.println("brandTerm = " + brandTerm);
        }

    }


    public static void SearchAggregationQuery2(@NotNull RestHighLevelClient client) throws IOException {
        SearchRequest searchRequest = new SearchRequest( );
        searchRequest.indices("user");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder( );

        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("genderGroup").field("age").order(BucketOrder.count(true));

        searchSourceBuilder.aggregation(aggregationBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println("response = " + response);

        Terms brandTerm = response.getAggregations( ).get("genderGroup");
        for (Terms.Bucket bucket : brandTerm.getBuckets( )) {
            System.out.println(bucket.getKey( ) + ":" + bucket.getDocCount( ));

            System.out.println("brandTerm = " + brandTerm);
        }
    }









}
